<?php
namespace app\api\controller;

use app\common\controller\BaseController;
use app\common\repositories\apps\AppsAccessRepository;
use app\common\repositories\apps\AppsAppsRepository;
use app\common\repositories\apps\AppsEventRepository;
use app\common\repositories\apps\AppsRepository;
use app\common\repositories\apps\AppsWebRepository;
use app\common\service\PerformanceService;
use support\Container;

/**
 * Apps
 */
class AppsController extends BaseController
{
    protected $repository;

    public function __construct()
    {
        $this->repository = new AppsRepository();
    }

    /**
     * @desc: get list
     * @author: generate
     */
    public function list()
    {
        $user_id = request()->user->id ?? 0;
        
        // Use performance optimization with caching
        $refresh = request()->get('refresh', false);
        $data = PerformanceService::getCachedAppsList($user_id, $refresh);
        
        // Apply pagination if needed
        $page = (int)request()->get('page', 1);
        $limit = (int)request()->get('limit', 10);
        $offset = ($page - 1) * $limit;
        
        $total = count($data);
        $list = array_slice($data, $offset, $limit);
        
        $result = [
            'code' => 200, 
            'data' => [
                'list' => $list,
                'total' => $total,
                'page' => $page,
                'limit' => $limit
            ]
        ];
        return json($result);
    }

    /**
     * @desc: create one Apps
     * @param varchar $name                       
     * @param varchar $android_scheme_url 
     * @param varchar $ios_scheme_url     
     * @param varchar $universal_links    
     * @param varchar $package_name       
     * @param tinyint $is_huawei          
     * @param tinyint $is_xiaomi          
     * @param tinyint $is_vivo            
     * @param tinyint $is_oppo            
     * @param tinyint $is_honour          
     * @param tinyint $is_yyb             
     * @param varchar $icon               
     * @param varchar $banner             
     * @param int     $user_id            
     * @param array     $stores   
     * @author: generate
     */
    public function create()
    {
        $user_id = request()->user->id ?? 0;
        $name = request()->post('name','');
        $android_scheme_url = request()->post('android_scheme_url','');
        $ios_scheme_url = request()->post('ios_scheme_url','');
        $universal_links = request()->post('universal_links','');
        $package_name = request()->post('package_name','');
        $is_huawei = request()->post('is_huawei',0);
        $is_xiaomi = request()->post('is_xiaomi',0);
        $is_vivo = request()->post('is_vivo',0);
        $is_oppo = request()->post('is_oppo',0);
        $is_honour = request()->post('is_honour',0);
        $is_yyb = request()->post('is_yyb',0);
        $icon = request()->post('icon','');
        $banner = request()->post('banner','');
        $stores = request()->post('stores',[]);

        $huawei_down_url = request()->post('huawei_down_url','');
        $xiaomi_down_url = request()->post('xiaomi_down_url','');
        $vivo_down_url = request()->post('vivo_down_url','');
        $oppo_down_url = request()->post('oppo_down_url','');
        $honour_down_url = request()->post('honour_down_url','');
        $yyb_down_url = request()->post('yyb_down_url','');

        $result = $this->repository->createOneApps(
            $name,
            $android_scheme_url,
            $ios_scheme_url,
            $universal_links,
            $package_name,
            $is_huawei,
            $is_xiaomi,
            $is_vivo,
            $is_oppo,
            $is_honour,
            $is_yyb,
            $icon,
            $banner,
            $user_id,
            $stores,
            $huawei_down_url,
            $xiaomi_down_url,
            $vivo_down_url,
            $oppo_down_url,
            $honour_down_url,
            $yyb_down_url
        );
        
        // Clear user cache after creating new app
        if ($result['code'] === 200) {
            PerformanceService::clearUserCache($user_id);
        }
        
        return json($result);
    }

    /**
     * @desc: update one Apps
     * @param varchar $name               
     * @param varchar $appkey             
     * @param varchar $android_scheme_url 
     * @param varchar $ios_scheme_url     
     * @param varchar $universal_links    
     * @param varchar $package_name       
     * @param tinyint $is_huawei          
     * @param tinyint $is_xiaomi          
     * @param tinyint $is_vivo            
     * @param tinyint $is_oppo            
     * @param tinyint $is_honour          
     * @param tinyint $is_yyb             
     * @param varchar $icon               
     * @param varchar $banner             
     * @param int     $user_id      
     * @param array     $stores       
     * @author: generate
     */
    public function update($id)
    {
        $user_id = request()->user->id ?? 0;
        
        // 验证应用所有权 - 确保用户只能修改自己的应用
        $app = $this->repository->getDetail($id);
        if (empty($app)) {
            return json(['code' => 0, 'msg' => '应用不存在']);
        }
        
        if ($app['user_id'] != $user_id) {
            return json(['code' => 0, 'msg' => '您没有权限修改此应用']);
        }
        
        $name = request()->post('name','');
        $android_scheme_url = request()->post('android_scheme_url','');
        $ios_scheme_url = request()->post('ios_scheme_url','');
        $universal_links = request()->post('universal_links','');
        $package_name = request()->post('package_name','');
        $is_huawei = request()->post('is_huawei',0);
        $is_xiaomi = request()->post('is_xiaomi',0);
        $is_vivo = request()->post('is_vivo',0);
        $is_oppo = request()->post('is_oppo',0);
        $is_honour = request()->post('is_honour',0);
        $is_yyb = request()->post('is_yyb',0);
        $icon = request()->post('icon','');
        $banner = request()->post('banner','');
        $stores = request()->post('stores',[]);

        $huawei_down_url = request()->post('huawei_down_url','');
        $xiaomi_down_url = request()->post('xiaomi_down_url','');
        $vivo_down_url = request()->post('vivo_down_url','');
        $oppo_down_url = request()->post('oppo_down_url','');
        $honour_down_url = request()->post('honour_down_url','');
        $yyb_down_url = request()->post('yyb_down_url','');

        $result = $this->repository->updateOneApps(
            $id, 
            $name,
            $android_scheme_url,
            $ios_scheme_url,
            $universal_links,
            $package_name,
            $is_huawei,
            $is_xiaomi,
            $is_vivo,
            $is_oppo,
            $is_honour,
            $is_yyb,
            $icon,
            $banner,
            $user_id,
            $stores,
            $huawei_down_url,
            $xiaomi_down_url,
            $vivo_down_url,
            $oppo_down_url,
            $honour_down_url,
            $yyb_down_url
        );
        return json($result);
    }
    /**
     * @desc: get one Apps detail
     * @author: generate
     */
    public function detail($id){
        $user_id = request()->user->id ?? 0;
        
        // 验证应用所有权 - 确保用户只能查看自己的应用详情
        $data = $this->repository->getDetail($id);
        if (empty($data)) {
            return json(['code' => 0, 'msg' => '应用不存在']);
        }
        
        if ($data['user_id'] != $user_id) {
            return json(['code' => 0, 'msg' => '您没有权限查看此应用']);
        }
        
        $result = ['code' => 200, 'data' => $data];
        return json($result);
    }
    /**
     * @desc: statistics
     * @author: xiaohp
     */
    public function statistics($id){
        $user_id = request()->user->id ?? 0;
        
        // 验证应用所有权 - 确保用户只能查看自己应用的统计数据
        $app = $this->repository->getDetail($id);
        if (empty($app)) {
            return json(['code' => 0, 'msg' => '应用不存在']);
        }
        
        if ($app['user_id'] != $user_id) {
            return json(['code' => 0, 'msg' => '您没有权限查看此应用的统计数据']);
        }
        
        // Use performance optimization with caching
        $refresh = request()->get('refresh', false);
        $data = PerformanceService::getCachedAppStats($app['appkey'], $refresh);
        
        $result = ['code' => 200, 'data' => $data];
        return json($result);
    }

    /**
     * @desc: get info
     * @author: generate
     */
    public function info(){
        $startTime = microtime(true);
        $appinfo = request()->appinfo ?? [];
        $appkey = request()->appkey ?? '';
        $version = request()->version ?? '';
        $fingerprint = request()->fingerprint ?? '';
        $customInfo = request()->post('customInfo',[]);
        $deviceInfo = request()->post('deviceInfo',[]);
        $platform = request()->post('platform', 'unknown');
        $sdkVersion = request()->post('sdkVersion', 'unknown');
        
        // 使用增强的SDK服务处理请求
        $result = null;
        if($appkey && $fingerprint && $version){
            // 验证请求参数
            $validationErrors = Container::make(\app\common\service\SDKService::class)->validateRequestParams([
                'appkey' => $appkey,
                'version' => $version,
                'fingerprint' => $fingerprint
            ], ['appkey', 'version', 'fingerprint']);
            
            if (!empty($validationErrors)) {
                // 记录失败的SDK使用日志，包含平台和版本信息
                Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                    $appkey, 'device_info', false, null, $platform, $sdkVersion, implode(', ', $validationErrors)
                );
                $result = ['code' => 400, 'msg' => '参数验证失败: ' . implode(', ', $validationErrors)];
            } else {
                try {
                    // 使用增强的设备信息处理
                    $deviceResult = Container::make(AppsWebRepository::class)->createOneAppsWeb($appkey,$deviceInfo,$customInfo,$fingerprint,$version);
                    
                    // 记录成功的SDK使用日志，包含平台和版本信息
                    $responseTime = round((microtime(true) - $startTime) * 1000); // 毫秒
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'device_info', true, $responseTime, $platform, $sdkVersion
                    );
                    
                    $result = ['code' => 200, 'data' => $appinfo];
                } catch (\Exception $e) {
                    // 记录失败的SDK使用日志，包含错误信息
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'device_info', false, null, $platform, $sdkVersion, $e->getMessage()
                    );
                    $result = ['code' => 500, 'msg' => '处理设备信息时出错'];
                }
            }
        } else {
            $result = ['code' => 200, 'data' => $appinfo];
        }
        
        return json($result);
    }

    /**
     * @desc: get custom
     * @author: generate
     */
    public function custom(){
        $startTime = microtime(true);
        $appinfo = request()->appinfo ?? [];
        $appkey = request()->appkey ?? '';
        $version = request()->version ?? '';
        $fingerprint = request()->fingerprint ?? '';
        $deviceInfo = request()->post('deviceInfo',[]);
        $platform = request()->post('platform', 'unknown');
        $sdkVersion = request()->post('sdkVersion', 'unknown');
        
        $custom = [];
        $result = null;
        
        if($appkey && $fingerprint && $version){
            // 验证请求参数
            $validationErrors = Container::make(\app\common\service\SDKService::class)->validateRequestParams([
                'appkey' => $appkey,
                'version' => $version,
                'fingerprint' => $fingerprint
            ], ['appkey', 'version', 'fingerprint']);
            
            if (!empty($validationErrors)) {
                // 记录失败的SDK使用日志，包含平台和版本信息
                Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                    $appkey, 'custom_params', false, null, $platform, $sdkVersion, implode(', ', $validationErrors)
                );
                $result = ['code' => 400, 'msg' => '参数验证失败: ' . implode(', ', $validationErrors)];
            } else {
                try {
                    // 使用增强的自定义参数处理
                    Container::make(AppsAppsRepository::class)->createOneAppsApps($appkey,$deviceInfo,$fingerprint,$version);
                    $custom = Container::make(AppsWebRepository::class)->getFirstCustom($appkey,$fingerprint);
                    
                    // 记录成功的SDK使用日志，包含平台和版本信息
                    $responseTime = round((microtime(true) - $startTime) * 1000);
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'custom_params', true, $responseTime, $platform, $sdkVersion
                    );
                    
                    $result = ['code' => 200, 'data' => ['custom' => $custom,'appinfo' => $appinfo,'version' => $version,'fingerprint' => $fingerprint,'appkey' => $appkey]];
                } catch (\Exception $e) {
                    // 记录失败的SDK使用日志，包含错误信息
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'custom_params', false, null, $platform, $sdkVersion, $e->getMessage()
                    );
                    $result = ['code' => 500, 'msg' => '处理自定义参数时出错'];
                }
            }
        } else {
            $result = ['code' => 200, 'data' => ['custom' => $custom,'appinfo' => $appinfo,'version' => $version,'fingerprint' => $fingerprint,'appkey' => $appkey]];
        }
        
        return json($result);
    }
    /**
     * @desc: get event
     * @author: generate
     */
    public function event(){
        $startTime = microtime(true);
        $appinfo = request()->appinfo ?? [];
        $appkey = request()->appkey ?? '';
        $version = request()->version ?? '';
        $fingerprint = request()->fingerprint ?? '';
        $deviceInfo = request()->post('deviceInfo',[]);
        $platform = request()->post('platform', 'unknown');
        $sdkVersion = request()->post('sdkVersion', 'unknown');
        
        $result = null;
        
        if($appkey && $fingerprint && $version){
            // 验证请求参数
            $validationErrors = Container::make(\app\common\service\SDKService::class)->validateRequestParams([
                'appkey' => $appkey,
                'version' => $version,
                'fingerprint' => $fingerprint
            ], ['appkey', 'version', 'fingerprint']);
            
            if (!empty($validationErrors)) {
                // 记录失败的SDK使用日志，包含平台和版本信息
                Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                    $appkey, 'event_tracking', false, null, $platform, $sdkVersion, implode(', ', $validationErrors)
                );
                $result = ['code' => 400, 'msg' => '参数验证失败: ' . implode(', ', $validationErrors)];
            } else {
                try {
                    // 使用增强的事件追踪处理
                    Container::make(AppsEventRepository::class)->createOneAppsEvent($appkey,$deviceInfo,$fingerprint,$version);
                    
                    // 记录成功的SDK使用日志，包含平台和版本信息
                    $responseTime = round((microtime(true) - $startTime) * 1000);
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'event_tracking', true, $responseTime, $platform, $sdkVersion
                    );
                    
                    $result = ['code' => 200, 'data' => ['appinfo' => $appinfo,'version' => $version,'fingerprint' => $fingerprint,'appkey' => $appkey]];
                } catch (\Exception $e) {
                    // 记录失败的SDK使用日志，包含错误信息
                    Container::make(\app\common\service\SDKService::class)->logSDKUsage(
                        $appkey, 'event_tracking', false, null, $platform, $sdkVersion, $e->getMessage()
                    );
                    $result = ['code' => 500, 'msg' => '处理事件追踪时出错'];
                }
            }
        } else {
            $result = ['code' => 200, 'data' => ['appinfo' => $appinfo,'version' => $version,'fingerprint' => $fingerprint,'appkey' => $appkey]];
        }
        
        return json($result);
    }

    /**
     * @desc: delete one Apps
     * @author: generate
     * @param int $id
     */
    public function delete($id){
        $user_id = request()->user->id ?? 0;
        
        // 验证应用所有权 - 确保用户只能删除自己的应用
        $app = $this->repository->getDetail($id);
        if (empty($app)) {
            return json(['code' => 0, 'msg' => '应用不存在']);
        }
        
        if ($app['user_id'] != $user_id) {
            return json(['code' => 0, 'msg' => '您没有权限删除此应用']);
        }
        
        $result = $this->repository->delOneApps($id);
        return json($result);
    }

    /**
     * @desc: get membership info
     * @author: generate
     */
    public function membershipInfo(){
        $user_id = request()->user->id ?? 0;
        
        $membershipInfo = Container::make(\app\common\service\MembershipService::class)->getAppLimitInfo($user_id);
        $expiryInfo = Container::make(\app\common\service\MembershipService::class)->checkMembershipExpiry($user_id);
        
        $result = [
            'code' => 200, 
            'data' => [
                'membership' => $membershipInfo,
                'expiry_warning' => $expiryInfo
            ]
        ];
        return json($result);
    }

    /**
     * @desc: get SDK configuration
     * @author: generate
     */
    public function sdkConfig(){
        $appkey = request()->get('appkey', '');
        $user_id = request()->user->id ?? 0;
        
        if (empty($appkey)) {
            return json(['code' => 400, 'msg' => '应用密钥不能为空']);
        }
        
        // 验证应用所有权
        $app = $this->repository->getFirstApps(['appkey' => $appkey]);
        if (empty($app) || $app['user_id'] != $user_id) {
            return json(['code' => 403, 'msg' => '无权访问此应用的SDK配置']);
        }
        
        try {
            $sdkConfig = [
                'appkey' => $appkey,
                'api_base_url' => config('app.api_base_url', 'https://api.xapptool.com'),
                'timeout' => config('app.sdk_timeout', 30),
                'retry_count' => config('app.sdk_retry_count', 3),
                'retry_delay' => config('app.sdk_retry_delay', 1),
                'cache_enabled' => config('app.sdk_cache_enabled', true),
                'cache_ttl' => config('app.sdk_cache_ttl', 3600),
                'endpoints' => [
                    'device_info' => '/api/apps/info',
                    'custom_params' => '/api/apps/custom',
                    'event_tracking' => '/api/apps/event',
                    'membership_info' => '/api/apps/membershipInfo'
                ],
                'supported_platforms' => ['android', 'ios', 'web', 'react', 'vue', 'unity'],
                'version' => '2.0.0',
                'last_updated' => date('Y-m-d H:i:s')
            ];
            
            return json(['code' => 200, 'data' => $sdkConfig]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取SDK配置失败']);
        }
    }

    /**
     * @desc: get SDK usage statistics
     * @author: generate
     */
    public function sdkStats(){
        $appkey = request()->get('appkey', '');
        $days = request()->get('days', 30);
        $user_id = request()->user->id ?? 0;
        
        if (empty($appkey)) {
            return json(['code' => 400, 'msg' => '应用密钥不能为空']);
        }
        
        if ($days < 1 || $days > 365) {
            return json(['code' => 400, 'msg' => '统计天数必须在1-365之间']);
        }
        
        // 验证应用所有权
        $app = $this->repository->getFirstApps(['appkey' => $appkey]);
        if (empty($app) || $app['user_id'] != $user_id) {
            return json(['code' => 403, 'msg' => '无权访问此应用的SDK统计数据']);
        }
        
        try {
            $statsRepository = Container::make(\app\common\repository\SDKStatsRepository::class);
            $usageStats = $statsRepository->getUsageStats($appkey, $days);
            $errorStats = $statsRepository->getErrorStats($appkey, $days);
            $performanceStats = $statsRepository->getPerformanceStats($appkey, $days);
            
            $stats = [
                'appkey' => $appkey,
                'period' => $days,
                'usage' => $usageStats,
                'errors' => $errorStats,
                'performance' => $performanceStats,
                'summary' => [
                    'total_requests' => array_sum(array_column($usageStats, 'count')),
                    'success_rate' => $this->calculateSuccessRate($usageStats),
                    'avg_response_time' => $this->calculateAvgResponseTime($performanceStats),
                    'top_errors' => $this->getTopErrors($errorStats)
                ]
            ];
            
            return json(['code' => 200, 'data' => $stats]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取SDK统计数据失败']);
        }
    }

    /**
     * 计算成功率
     */
    private function calculateSuccessRate($usageStats){
        if (empty($usageStats)) return 0;
        
        $total = 0;
        $success = 0;
        foreach ($usageStats as $stat) {
            $total += $stat['count'];
            if ($stat['status'] == 'success') {
                $success += $stat['count'];
            }
        }
        
        return $total > 0 ? round(($success / $total) * 100, 2) : 0;
    }

    /**
     * 计算平均响应时间
     */
    private function calculateAvgResponseTime($performanceStats){
        if (empty($performanceStats)) return 0;
        
        $totalTime = 0;
        $count = 0;
        foreach ($performanceStats as $stat) {
            if ($stat['avg_response_time'] > 0) {
                $totalTime += $stat['avg_response_time'] * $stat['count'];
                $count += $stat['count'];
            }
        }
        
        return $count > 0 ? round($totalTime / $count, 2) : 0;
    }

    /**
     * 获取主要错误
     */
    private function getTopErrors($errorStats){
        if (empty($errorStats)) return [];
        
        usort($errorStats, function($a, $b) {
            return $b['count'] - $a['count'];
        });
        
        return array_slice($errorStats, 0, 5);
    }

}